package com.jeecg.jing.controller;

import com.jeecg.jing.entity.ZTakeinEntity;
import com.jeecg.jing.entity.excel.*;
import com.jeecg.jing.service.ZTakeinServiceI;
import org.hibernate.criterion.Restrictions;
import org.jeecgframework.core.common.exception.BusinessException;
import org.jeecgframework.core.common.hibernate.qbc.CriteriaQuery;
import org.jeecgframework.core.common.model.json.DataGrid;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.vo.NormalExcelConstants;
import org.jeecgframework.tag.core.easyui.TagUtil;
import org.jeecgframework.tag.vo.datatable.SortDirection;
import org.jeecgframework.web.system.service.SystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class ControllerUtil {
    private static final Logger logger = LoggerFactory.getLogger(ControllerUtil.class);

    @Autowired
    private ZTakeinServiceI zTakeinService;
    @Autowired
    private SystemService systemService;


    public ModelAndView list(HttpServletRequest request) {
        String type = request.getParameter("type");
        String key = request.getParameter("key");
        String key2 = request.getParameter("key2");

        String viewName = "com/jeecg/jing/zTakeinList";
        if("huizong".equals(type)) {
            viewName = "com/jeecg/jing/zTakeinList_huizong";
        }
        if("xianjin".equals(key2)) {
            viewName = "com/jeecg/jing/zTakeinList_xianjin";
        }
        if("lixi".equals(key)) {
            viewName = "com/jeecg/jing/zTakeinList_lixi";
        }

        ModelAndView modelAndView = new ModelAndView(viewName);
        modelAndView.addObject("type", type);
        modelAndView.addObject("key", key);
        modelAndView.addObject("key2", key2);

        return modelAndView;
    }

    public void datagrid(ZTakeinEntity zTakein, HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
        CriteriaQuery cq = queryAndExport(zTakein, request, dataGrid);
        zTakeinService.getDataGridReturn(cq, true);

        List<ZTakeinEntity> results = dataGrid.getResults();
        Map<String, Map<String, Object>> map = processResult(results, request);
        TagUtil.datagrid(response, dataGrid, map);
    }

    public Map<String, Map<String, Object>> processResult(List<ZTakeinEntity> results, HttpServletRequest request) {
        String type = request.getParameter("type");
        String statusCondition = " <> '0' ";
        if(StringUtil.isNotEmpty(type)) {
            if("xianyou".equals(type)) {
                statusCondition = " = '1' ";
            } else if("daoqi".equals(type)) {
                statusCondition = " = '2' ";
            } else if("huizong".equals(type)) {
                statusCondition = " = '1' ";
            }
        }

        // 按客户统计：总销售额
        List<String> names = new ArrayList<String>();
        for (ZTakeinEntity z : results) {// 只统计查询结果中字段，防止数据量过大
            names.add("'" + z.getCustomName() + "'");
        }
        List<Object[]> sum = new ArrayList<Object[]>();
        if(names.size() > 0) {
            String sql = "select z.custom_name, sum(z.amount) sum_amount from z_takein z"
                    + " where z.status "+statusCondition+" and z.custom_name in (" + StringUtil.joinString(names, ",") + ") GROUP BY z.custom_name";
            sum = systemService.findListbySql(sql);
        }
        // 扩展‘客户量’字段
        Map<String, Map<String, Object>> map = new HashMap<String,Map<String,Object>>();
        List<String> rs = systemService.findListbySql("SELECT group_concat(r separator ',') from("
                + "SELECT CONCAT_WS('_', t.sale_name,count(1)) r from (SELECT DISTINCT a.sale_name, a.custom_name from z_takein a where a.status " + statusCondition
                + ") t GROUP BY t.sale_name) a ");
        for (ZTakeinEntity z : results) {
            Map<String,Object> m = new HashMap<String,Object>();
            String s = "0";
            String sum_amount = "0";

            // 客户量统计
            try {
                s = rs.get(0).split(z.getSaleName() + "_")[1].split(",")[0];
            } catch (Exception e) {
//                e.printStackTrace();
            }
            m.put("count", s);

            // 利息统计：金额*利率
            try {
                m.put("interest", z.getAmount().multiply(z.getRate()).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
            } catch (Exception e) {
                m.put("interest", "0");
//				e.printStackTrace();
            }

            // 按客户统计字段处理-------------------------------------------------
            try {
                for(Object[] item : sum) {
                    if(z.getCustomName().equals(item[0])) {
                        sum_amount = item[1].toString();
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            m.put("sum_amount", sum_amount);// 总销售额

            map.put(z.getId(), m);
        }
        return map;
    }


    /*
    * 导出excel和查询公用方法
    **/
    public CriteriaQuery queryAndExport(ZTakeinEntity zTakein, HttpServletRequest request, DataGrid dataGrid) {
        try {
            if(request.getQueryString().startsWith("exportXls")) {
                if(zTakein.getCustomName() != null)
                    zTakein.setCustomName(new String(zTakein.getCustomName().getBytes("iso-8859-1"), "utf-8"));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        CriteriaQuery cq = new CriteriaQuery(ZTakeinEntity.class, dataGrid);
        //查询条件组装器
        org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil.installHql(cq, zTakein, request.getParameterMap());
        try{
            //自定义追加查询条件
            String type = request.getParameter("type");
            if(StringUtil.isNotEmpty(type)) {
                if("xianyou".equals(type)) {
                    cq.eq("status", "1");
                } else if("daoqi".equals(type)) {
                    cq.eq("status", "2");
                } else if("huizong".equals(type)) {
//					cq.eq("status", "1");
                    // 汇总需要列出全部用户
                }
            }

            // 月报表特殊处理
            String key = request.getParameter("key");
            String takeinTime = request.getParameter("takeinTime2");
            if("yue".equals(key) && StringUtil.isNotEmpty(takeinTime)) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    Date parse = format.parse(takeinTime+"-01");
                    Calendar curMon = Calendar.getInstance();
                    curMon.setTime(parse);
                    Calendar nextMon = (Calendar) curMon.clone();
                    nextMon.add(Calendar.MONTH, 1);
                    cq.ge("takeinTime", curMon.getTime());
                    cq.lt("takeinTime", nextMon.getTime());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }

            // 现金利息处理
            String key2 = request.getParameter("key2");
            if("xianjin".equals(key2)) {
                cq.or(Restrictions.like("comment", "%现金%"), Restrictions.like("bankAccount", "%现金%"));
            }

            // 客户汇总
            if("huizong".equals(type)) {
                /*// 每个客户仅获取一个id，使用in子句达到显示统计结果的目的
				List<Object> ids = systemService.findListbySql("SELECT z.id from z_takein z where status = '1' GROUP BY z.custom_name");
                // 客户资金归零的也要显示
				List<Object> ids2 = systemService.findListbySql("SELECT a.id from z_takein a where a.custom_name not in(\n" +
						"SELECT z.custom_name from z_takein z where status = '1') GROUP BY a.custom_name");
				ids.addAll(ids2);*/
                List<Object> ids = systemService.findListbySql("SELECT z.id from z_takein z GROUP BY z.custom_name");
                cq.in("id", ids.toArray());
            }

            if("daoqi".equals(type)) {
                cq.addOrder("updateDate", SortDirection.desc);
            }
            cq.addOrder("createDate", SortDirection.desc);
            cq.addOrder("takeinTime", SortDirection.desc);
        }catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
        cq.add();
        return cq;
    }

    public String exportXls(ZTakeinEntity zTakein, HttpServletRequest request, DataGrid dataGrid, ModelMap modelMap) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        CriteriaQuery cq = queryAndExport(zTakein, request, dataGrid);
        List<ZTakeinEntity> zTakeins = this.zTakeinService.getListByCriteriaQuery(cq,false);
        Map<String, Map<String, Object>> map = processResult(zTakeins, request);

        List list = zTakeins;
        String fileName = "客户信息汇总";
        String title = fileName + "列表";
//		Class exportType = ZTakeinEntity.class;
        Class exportType = ZTakeinEntity_.class;
        String type = request.getParameter("type");
        String key = request.getParameter("key");
        String key2 = request.getParameter("key2");

        list = new ArrayList();
        if("xianyou".equals(type)) {
            exportType = ZTakeinEntity_Xianyou.class;
            fileName = "现有资金流水";
            title = fileName + "列表";
            if("lixi".equals(key)) {
                exportType = ZTakeinEntity_Lixi.class;
                fileName = "客户利息";
                title = fileName + "列表";
                if("xianjin".equals(key2)) {
                    exportType = ZTakeinEntity_Xianjin.class;
                    fileName = "客户现金利息明细";
                    title = fileName + "列表";
                }
            } else if("yue".equals(key)) {
                String takeinTime = request.getParameter("takeinTime2");
                fileName = takeinTime + "客户单月流水汇总";
                title = fileName + "列表";
            } else if("hongbao".equals(key)) {
                exportType = ZTakeinEntity_hongbao.class;
                fileName = "客户签单活动";
                title = fileName + "列表";
            }

        } else if("daoqi".equals(type)) {
            exportType = ZTakeinEntity_Daoqi.class;
            fileName = "客户资金到期汇总";
            title = fileName + "列表";
        } else if("huizong".equals(type)) {
            exportType = ZTakeinEntity_Huizong.class;
            fileName = "客户资金汇总";
            title = fileName + "列表";
        }
        Constructor constructor = exportType.getConstructors()[0];

//		try {
        for(ZTakeinEntity z : zTakeins) {
            Object t = constructor.newInstance();
            BeanUtils.copyProperties(z, t, exportType);
            if(ZTakeinEntity_Huizong.class.equals(exportType)) {// 客户量
                ZTakeinEntity_Huizong hz = (ZTakeinEntity_Huizong) t;
                hz.setCount(map.get(z.getId()).get("count").toString());
                hz.setAmount(new BigDecimal(map.get(z.getId()).get("sum_amount").toString()));
            } else if(ZTakeinEntity_Xianjin.class.equals(exportType)) {// 利息
                ZTakeinEntity_Xianjin xj = (ZTakeinEntity_Xianjin) t;
                xj.setInterest(map.get(z.getId()).get("interest").toString());
            }

            // 统一处理“到期日”、“到期时间”空白时的转换
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            if(z.getEndTime() == null) {
                if(z.getTakeinTime() != null)
                    t.getClass().getMethod("setEndDay", String.class).invoke(t, sdf.format(z.getTakeinTime()));
                try {
                    t.getClass().getMethod("setEndTime_", String.class).invoke(t, "活期");
                } catch (Exception e) {
                }
            } else {
                Calendar c = Calendar.getInstance();
                c.setTime(z.getEndTime());
                t.getClass().getMethod("setEndDay", String.class).invoke(t, c.get(Calendar.DAY_OF_MONTH) + "");
                try {
                    t.getClass().getMethod("setEndTime_", String.class).invoke(t, sdf.format(z.getEndTime()));
                } catch (Exception e) {
                }
            }

            list.add(t);
        }
//		} catch (Exception e) {
//			e.printStackTrace();
//		}

        modelMap.put(NormalExcelConstants.FILE_NAME, fileName);
        modelMap.put(NormalExcelConstants.CLASS, exportType);
        modelMap.put(NormalExcelConstants.PARAMS,new ExportParams(title, "导出人:"+ ResourceUtil.getSessionUser().getRealName(),
                "导出信息"));
        modelMap.put(NormalExcelConstants.DATA_LIST, list);
        return NormalExcelConstants.JEECG_EXCEL_VIEW;
    }
}
